package cn.exrick.xboot.social.controller;

/**
 * @Auther: xujiaxin
 * @Date: 12/20/21 22:47
 * @Description:
 */

import cn.exrick.xboot.core.common.constant.MemberConstant;
import cn.exrick.xboot.core.common.utils.ResultUtil;
import cn.exrick.xboot.core.common.utils.SecurityUtil;
import cn.exrick.xboot.core.common.utils.SnowFlakeUtil;
import cn.exrick.xboot.core.common.utils.WxAES;
import cn.exrick.xboot.core.common.vo.Result;
import cn.exrick.xboot.core.config.security.SecurityMemberDetails;
import cn.exrick.xboot.core.entity.AppMember;
import cn.exrick.xboot.core.entity.Member;
import cn.exrick.xboot.core.service.MemberService;
import cn.exrick.xboot.core.service.mybatis.IAppMemberService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
 * @author Exrickx
 */
@Slf4j
@RestController
@Api(tags = "会员接口")
@RequestMapping(value = "/xboot/social/weapp")
public class WeappController {

    @Value("${xboot.social.weapp.appId}")
    private String appId;

    @Value("${xboot.social.weapp.appSecret}")
    private String appSecret;

    @Value("${xboot.social.weapp.callbackUrl}")
    private String callbackUrl;

    private String XCX_AUTHORIZATION_CODE_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s" +
            "&secret=%s&js_code=%s&grant_type=authorization_code";

    @Autowired
    private StringRedisTemplate redisTemplate;

    private String SESSION_KEY = "SESSION_KEY_";

    @Autowired
    private MemberService memberService;

    @Autowired
    private IAppMemberService appMemberService;

    @Autowired
    private SecurityUtil securityUtil;


    @GetMapping("/login")
    public Result login(String code){

        String url = String.format(XCX_AUTHORIZATION_CODE_URL, appId, appSecret, code);
        String res = HttpUtil.get(url);
        System.out.println(res);
        JSONObject obj = JSONUtil.parseObj(res);
        String openid = obj.get("openid").toString();
        String session_key = obj.get("session_key").toString();
        redisTemplate.opsForValue().set(SESSION_KEY + openid, session_key, 60*60*12, TimeUnit.SECONDS);
        Boolean isNew = false;

        Member member = memberService.findByOpenIdAndPlatform(openid, MemberConstant.MEMBER_PLATFORM_WEAPP);
        // 无账号 注册
        if(null == member){
            member = new Member();


            member.setUsername(IdUtil.simpleUUID());
            member.setOpenId(openid);
            member.setType(MemberConstant.MEMBER_TYPE_NORMAL);
            member.setVipStatus(MemberConstant.MEMBER_STATUS_NORMAL);
            member.setPlatform(MemberConstant.MEMBER_PLATFORM_WEAPP);
            member = memberService.save(member);
            isNew = true;
        }

        // 登录
        String appToken = securityUtil.getAppToken(member.getUsername(), MemberConstant.MEMBER_PLATFORM_WEAPP);
        // 记录日志使用
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(new SecurityMemberDetails(member), null, null);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        Map<String, Object> result = new HashMap<>(16);
        result.put("isNew", isNew);
        result.put("token", appToken);
        return ResultUtil.data(result);
    }


    /**
     * 更新用户信息
     * @param member
     * @return
     */
    @PostMapping("setUserInfo")
    public Result setUserInfo(AppMember member) {
        AppMember mb = securityUtil.getCurrAppMember();
        BeanUtil.copyProperties(member,mb, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        appMemberService.updateById(mb);
        return ResultUtil.data(mb);
    }


    /**
     * 跟新手机号
     * @param ivData
     * @param encryptedData
     * @return
     * @throws Exception
     */
    @PostMapping("updateMobile")
    public Result<Object> updateMobile(@Param("ivData") String ivData, @Param("encryptedData") String encryptedData) throws Exception {
        AppMember member = securityUtil.getCurrAppMember();
        Object sessionKey = redisTemplate.opsForValue().get(SESSION_KEY  + member.getOpenId());
        String res = WxAES.wxDecrypt(encryptedData,sessionKey.toString(),ivData);
        JSONObject obj = JSONUtil.parseObj(res);
        String mobile = obj.get("phoneNumber").toString();
        member.setMobile(mobile);
        appMemberService.updateById(member);
        return ResultUtil.data(member);
    }


}
